package uiao.step6_annotation;

import uiao.step3_connection_holder.TransactionManager;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class TransactionEnabledAnnotationProxyManager {
    private TransactionManager transactionManager;

    public TransactionEnabledAnnotationProxyManager(TransactionManager transactionManager) {

        this.transactionManager = transactionManager;
    }

    public Object proxyFor(Object object) {
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new AnnotationTransactionInvocationHandler(object, transactionManager));
    }
}

class AnnotationTransactionInvocationHandler implements InvocationHandler {
    private Object proxied;
    private TransactionManager transactionManager;

    AnnotationTransactionInvocationHandler(Object object, TransactionManager transactionManager) {
        this.proxied = object;
        this.transactionManager = transactionManager;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] objects) throws Throwable {
        // 根据方法有无注解判断是否使用事务，如果没有直接调用invoke即可
        Method originalMethod = proxied.getClass().getMethod(method.getName(), method.getParameterTypes());
        if (!originalMethod.isAnnotationPresent(Transactional.class)) {
            System.out.println("无事务");
            return method.invoke(proxied, objects);
        }

        System.out.println("有事务");
        transactionManager.start();
        Object result = null;
        try {
            result = method.invoke(proxied, objects);
            transactionManager.commit();
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
            System.out.println("回滚");
            transactionManager.rollback();
        } finally {
            transactionManager.close();
        }
        return result;
    }
}
